package com.yljk.yljkproject.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alsk.rn.kit.RNKITTools;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.google.gson.Gson;
import com.hyphenate.EMCallBack;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMCmdMessageBody;
import com.hyphenate.chat.EMCursorResult;
import com.hyphenate.chat.EMCustomMessageBody;
import com.hyphenate.chat.EMFileMessageBody;
import com.hyphenate.chat.EMImageMessageBody;
import com.hyphenate.chat.EMLocationMessageBody;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;
import com.hyphenate.chat.EMVideoMessageBody;
import com.hyphenate.chat.EMVoiceMessageBody;
import com.hyphenate.chat.adapter.message.EMAMessageBody;
import com.luck.picture.lib.tools.PictureFileUtils;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.yilijk.base.network.config.BaseConfig;
import com.yilijk.base.network.config.BaseUrl;
import com.yilijk.base.utils.ALog;
import com.yilijk.base.utils.CommonUtils;
import com.yljk.servicemanager.constants.ConfigApi;
import com.yljk.yljkproject.immessageapl.HistoryApi;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

import static com.alsk.rn.common.util.ReactConst.TAG;

public class EMMessageUtils {

    private static EMMessage emmessage;

//    发送消息
    public static void kitSendMsg(ReactContext reactContext, ReadableMap readableMap, Promise promise){
        //接收数据取值
        String datajson = ReactUtils.INSTANCE.delNativeMap(readableMap.toString());
        ALog.d(TAG, "sendMessage: " + datajson);
        EMMessage emMessage = EMMessageUtils.sendMessage(reactContext, datajson);
        if (emMessage == null) {
            ALog.d("消息发送失败", "emMessage is null");
            return;
        }
        // 环信发送消息
        EMClient.getInstance().chatManager().sendMessage(emMessage);
        //发送消息回调
        emMessage.setMessageStatusCallback(new EMCallBack() {
            @Override
            public void onSuccess() {
                ALog.i("消息发送成功", "消息发送成功: "+emMessage);
                ALog.d("消息发送成功", "onSuccess: ");
                String s = EMMessageUtils.emMessageJson(emMessage, false);
                ALog.d(TAG, "onSuccess: " + s);
                promise.resolve(s);
                Intent intent = new Intent(BaseConfig.Receiver.BroadcastReceiver);
                intent.putExtra(ConfigApi.receiverMsg, true);
                intent.putExtra(ConfigApi.receiverUser, emMessage.getTo());
                // 0 单聊 1 群聊 2 聊天室
                intent.putExtra(ConfigApi.receiverMsgType, getMessageType(emMessage));
                //向广播接收器传递数据
                reactContext.sendBroadcast(intent);      //发送广播
                RNKITTools.INSTANCE.sendBroadcast(reactContext,"ReceiveOrdinaryChatMessage",s);
            }

            @Override
            public void onError(int i, String s) {
                ALog.d("消息发送失败", "onError: " + s);
            }

            @Override
            public void onProgress(int i, String s) {
            }
        });
    }
    //回调消息判断逻辑
    public static String emMessageJson(EMMessage emmessage, boolean isRecall) {
        HashMap<String, Object> messageMap = new HashMap<>();
        HashMap<String, Object> bodymap = new HashMap<>();
        EMMessage.Type type = emmessage.getType();
        if (type == EMMessage.Type.TXT) {
            messageMap.put("msgType", 0);
            EMTextMessageBody body = (EMTextMessageBody) emmessage.getBody();
            if (body != null && body.getMessage() != null) {
                String message = body.getMessage();
                bodymap.put("text", body.getMessage());
            }
        } else if (type == EMMessage.Type.IMAGE) {
            messageMap.put("msgType", 1);
            EMImageMessageBody body = (EMImageMessageBody) emmessage.getBody();
            if (body != null) {
                int width = body.getWidth();
                String fileName = body.getFileName();
                int height = body.getHeight();
                String thumbnailUrl = body.getThumbnailUrl();
                String thumbnailSecret = body.getThumbnailSecret();
                bodymap.put("filename", body.getFileName());
                bodymap.put("height", body.getHeight());
                bodymap.put("thumbnailsecret", body.getThumbnailSecret());
                bodymap.put("thumbnailurl", body.getThumbnailUrl());
                bodymap.put("width", body.getWidth());
                bodymap.put("remotePath", body.getRemoteUrl());
            }
        } else if (type == EMMessage.Type.VOICE) {
            messageMap.put("msgType", 4);
            EMVoiceMessageBody body = (EMVoiceMessageBody) emmessage.getBody();
            if (body != null) {
                bodymap.put("localurl", body.getLocalUrl());
                bodymap.put("duration", body.getLength());
                bodymap.put("thumbnailRemotePath", body.getRemoteUrl());
                bodymap.put("secret", body.getSecret());
                bodymap.put("describecontents", body.describeContents());
                bodymap.put("remotePath", body.getRemoteUrl());
            }
            File path = new File(body.getLocalUrl());
            if (path != null && path.exists()) {
                path.delete();
            }
        } else if (type == EMMessage.Type.CUSTOM) {
            messageMap.put("msgType", 7);
            EMCustomMessageBody body = (EMCustomMessageBody) emmessage.getBody();
            HashMap<String, Object> paramsMap = new HashMap<>();
            if (body != null) {
                Set<Map.Entry<String, Object>> entries = paramsMap.entrySet();
                for (Map.Entry<String, Object> entrie : entries
                ) {
                    paramsMap.put(entrie.getKey(), entrie.getValue());
                }
                bodymap.put("customExt", body.getParams());
                bodymap.put("event", body.event());
                ALog.i("EVENT", "emMessageJson: EVENT" + body.event());
                bodymap.put("ext", paramsMap);
            }
        } else if (type == EMMessage.Type.CMD) {
            messageMap.put("msgType", 6);
            EMCmdMessageBody body = (EMCmdMessageBody) emmessage.getBody();
            if (body != null) {
                bodymap.put("action", body.action());
                bodymap.put("params", body.getParams());
            }
        }
        messageMap.put("timestamp", emmessage.getMsgTime());
        messageMap.put("from", emmessage.getFrom());
        messageMap.put("messageId", emmessage.getMsgId());
        messageMap.put("userName", emmessage.getUserName());
        messageMap.put("body", bodymap);
        messageMap.put("to", emmessage.getTo());
        messageMap.put("ext", emmessage.ext());
        ALog.d("EXT", "emMessageJson: " + emmessage.ext());
        messageMap.put("result", true);
        messageMap.put("isRecall", isRecall);
        messageMap.put("chatType", EMMessageUtils.getMessageType(emmessage));
        String s = new Gson().toJson(messageMap);
        return s;
    }

    //异地登录提示

    public static EMMessage sendMessage(Context context, String datajson) {
        try {
            JSONObject jsonObject = new JSONObject(datajson);
            String to = jsonObject.getString("to");
            String ext = jsonObject.getString("ext");
            int msgType = jsonObject.getInt("msgType");
            if (msgType == EMAMessageBody.EMAMessageBodyType_TEXT) {
                //文本类型 0
                String text = jsonObject.getString("text");
                String content = CommonUtils.decodeUTF8(text);
                ALog.d("发送文本消息", "sendMessage: " + content);
                emmessage = EMMessage.createTxtSendMessage(content, to);
            } else if (msgType == EMAMessageBody.EMAMessageBodyType_IMAGE) {
                //图片类型 1
                String uri = jsonObject.getString("imgUrl");
//            CommonUtils.getModuleCommonUtils().Uri2Path(context,uri);
                //imageUri为图片本地资源标志符，false为不发送原图（默认超过100k的图片会压缩后发给对方），需要发送原图传true
                emmessage = EMMessage.createImageSendMessage(uri, false, to);
                //如果是群聊，设置chattype，默认是单聊
            } else if (msgType == EMAMessageBody.EMAMessageBodyType_VIDEO) {
                //视频类型 2

            } else if (msgType == EMAMessageBody.EMAMessageBodyType_LOCATION) {
                //位置类型 3

            } else if (msgType == EMAMessageBody.EMAMessageBodyType_VOICE) {
                //音频类型 4
                //voiceUri为语音文件本地资源标志符，length为录音时间(秒)
                emmessage = EMMessage.createVoiceSendMessage(Uri.parse(jsonObject.getString("filePath")), jsonObject.getInt("fileTimeLength"), to);

            } else if (msgType == EMAMessageBody.EMAMessageBodyType_FILE) {
                //文件类型 5

            } else if (msgType == EMAMessageBody.EMAMessageBodyType_COMMAND) {
                //类型 6
                EMMessage customMessage = EMMessage.createSendMessage(EMMessage.Type.CUSTOM);
                ALog.i("CMD", "sendMessage: " + datajson);
            } else if (msgType == EMAMessageBody.EMAMessaeBody_Type_CUSTOM) {
                //自定义消息 7
                EMMessage customMessage = EMMessage.createSendMessage(EMMessage.Type.CUSTOM);
            }
            if (emmessage == null){
                Toast.makeText(context, "消息解析错误", Toast.LENGTH_SHORT).show();
            }else{
                Map<String, Object> extMap = (Map<String, Object>) JSON.parse(ext);
                Set<Map.Entry<String, Object>> entries = extMap.entrySet();
                Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> next = iterator.next();
                    if (next != null) {
                        if (next.getValue() instanceof Long) {
                            emmessage.setAttribute((String) next.getKey(), (long) next.getValue());
                        } else if (next.getValue() instanceof String) {
                            emmessage.setAttribute((String) next.getKey(), (String) next.getValue());
                        } else if (next.getValue() instanceof Integer) {
                            emmessage.setAttribute((String) next.getKey(), (int) next.getValue());
                        } else if (next.getValue() instanceof BigDecimal) {
                            String s1 = String.valueOf(next.getValue());
                            emmessage.setAttribute(next.getKey(), s1);
                        } else if (next.getValue() instanceof JSONArray) {
                            emmessage.setAttribute((String) next.getKey(), (JSONArray) next.getValue());
                        } else if (next.getValue() instanceof Double) {
                            emmessage.setAttribute((String) next.getKey(), String.valueOf(next.getValue()).toString());
                        } else if (next.getValue() instanceof com.alibaba.fastjson.JSONObject) {
                            String s1 = String.valueOf(next.getValue()).toString();
                            org.json.JSONObject jsonObject1 = new org.json.JSONObject(s1);
                            emmessage.setAttribute((String) next.getKey(), jsonObject1);
                        }
                    }
                }
            }
            if (jsonObject.has("chatType")){
                int chatTypeStatus = jsonObject.getInt("chatType");
                if (chatTypeStatus == 0){
                    emmessage.setChatType(EMMessage.ChatType.Chat);
                }else if (chatTypeStatus == 1){
                    emmessage.setChatType(EMMessage.ChatType.GroupChat);
                }else if (chatTypeStatus == 2){
                    emmessage.setChatType(EMMessage.ChatType.ChatRoom);
                }else{
                    emmessage.setChatType(EMMessage.ChatType.Chat);
                }
            }
            return emmessage;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 清空图片缓存，包括裁剪、压缩后的图片
     */
    public static void clearCache(Activity activity) {
        RxPermissions permissions = new RxPermissions(activity);
        permissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Boolean aBoolean) {
                if (aBoolean) {
                    //清除缓存
                    PictureFileUtils.deleteCacheDirFile(activity);
                }
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });
    }


    public static void history2Json(EMCursorResult<EMMessage> emMessageEMCursorResult, HistoryApi historyApi) {
        HashMap<String, Object> messageData = new HashMap<>();
        List<EMMessage> data = emMessageEMCursorResult.getData();
        for (int i = 0; i < data.size(); i++) {
            if (data.get(i).getType() == EMMessage.Type.CMD) {
                data.remove(i);
            }
        }
        Object[] list = new Object[data.size()];
        for (int i = 0; i < data.size(); i++) {
            HashMap<String, Object> messageList = new HashMap<>();
            HashMap<String, Object> messagebody = new HashMap<>();
            EMMessage emMessage = data.get(i);
            messageList.put("username", emMessage.getUserName());
            messageList.put("timestamp", emMessage.getMsgTime());
            messageList.put("messageId", emMessage.getMsgId());
            messageList.put("ext", emMessage.ext());
            EMMessage.Type type = emMessage.getType();
            switch (type) {
                case TXT:
                    messageList.put("msgType", 0);
                    break;
                case IMAGE:
                    messageList.put("msgType", 1);
                    break;
                case VIDEO:
                    messageList.put("msgType", 2);
                    break;
                case LOCATION:
                    messageList.put("msgType", 3);
                    break;
                case VOICE:
                    messageList.put("msgType", 4);
                    break;
                case FILE:
                    messageList.put("msgType", 5);
                    break;
                case CMD:
                    messageList.put("msgType", 6);
                    break;
                case CUSTOM:
                    messageList.put("msgType", 7);
                    break;

            }
            messageList.put("chattype", emMessage.getChatType());
            messageList.put("from", emMessage.getFrom());
            messageList.put("to", emMessage.getTo());
            if (emMessage.getType() == EMMessage.Type.TXT) {
                EMTextMessageBody body = (EMTextMessageBody) emMessage.getBody();
                if (body != null && body.getMessage() != null) {
                    messagebody.put("text", body.getMessage());
                }
            } else if (emMessage.getType() == EMMessage.Type.IMAGE) {
                EMImageMessageBody body = (EMImageMessageBody) emMessage.getBody();
                messagebody.put("filename", body.getFileName());
                messagebody.put("height", body.getHeight());
                messagebody.put("thumbnailsecret", body.getThumbnailSecret());
                messagebody.put("thumbnailurl", body.getThumbnailUrl());
                messagebody.put("width", body.getWidth());
                messagebody.put("remotePath", body.getRemoteUrl());
            } else if (emMessage.getType() == EMMessage.Type.VOICE) {
                EMVoiceMessageBody body = (EMVoiceMessageBody) emMessage.getBody();
                messagebody.put("localurl", body.getLocalUrl());
                messagebody.put("duration", body.getLength());
                messagebody.put("remotePath", body.getRemoteUrl());
                messagebody.put("secret", body.getSecret());
                messagebody.put("describecontents", body.describeContents());
            } else if (emMessage.getType() == EMMessage.Type.VIDEO) {
                EMVideoMessageBody body = (EMVideoMessageBody) emMessage.getBody();
                messagebody.put("duration", body.getDuration());
                messagebody.put("loaclthumb", body.getLocalThumb());
                messagebody.put("thumbnailheight", body.getThumbnailHeight());
                messagebody.put("thumbnailsercet", body.getThumbnailSecret());
                messagebody.put("thumbnailurl", body.getThumbnailUrl());
                messagebody.put("thumbnailwidth", body.getThumbnailWidth());
                messagebody.put("videofilelength", body.getVideoFileLength());
            } else if (emMessage.getType() == EMMessage.Type.CMD) {
                EMCmdMessageBody body = (EMCmdMessageBody) emMessage.getBody();
                messagebody.put("params", body.getParams());
                messagebody.put("action", body.action());

            } else if (emMessage.getType() == EMMessage.Type.FILE) {
                EMFileMessageBody body = (EMFileMessageBody) emMessage.getBody();
                messagebody.put("filename", body.getFileName());
                messagebody.put("localurl", body.getLocalUrl());
                messagebody.put("remoteurl", body.getRemoteUrl());
                messagebody.put("secret", body.getSecret());

            } else if (emMessage.getType() == EMMessage.Type.LOCATION) {
                EMLocationMessageBody body = (EMLocationMessageBody) emMessage.getBody();
                messagebody.put("address", body.getAddress());
                messagebody.put("latitude", body.getLatitude());
                messagebody.put("longitude", body.getLongitude());

            } else if (emMessage.getType() == EMMessage.Type.CUSTOM) {
                EMCustomMessageBody body = (EMCustomMessageBody) emMessage.getBody();
                Map<String, String> params = body.getParams();
                String event = body.event();
                int describeContents = body.describeContents();
                Set<Map.Entry<String, String>> entries = params.entrySet();
                HashMap<String, Object> paramsMap = new HashMap<>();
                for (Map.Entry<String, String> entrie : entries
                ) {
                    paramsMap.put(entrie.getKey(), entrie.getValue());
                }
                messagebody.put("customExt", params);
                messagebody.put("event", event);
                messagebody.put("ext", paramsMap);
            }
            messageList.put("body", messagebody);
            list[i] = messageList;
        }
        messageData.put("cursor", emMessageEMCursorResult.getCursor());
        messageData.put("list", list);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("result", messageData);
        historyApi.onSuccess(CommonUtils.getModuleCommonUtils().getMaptoJson(hashMap));
    }

    public static int getMessageType(EMMessage emMessage){
        if (emMessage.getChatType() == EMMessage.ChatType.Chat){
            return 0;
        }else if (emMessage.getChatType() == EMMessage.ChatType.GroupChat){
            return 1;
        }else{
            return 2;
        }
    }

}
